package com.tuo51.components.intercepter;

import com.tuo51.foudation.exception.BusinessException;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.model.MemVerificationCache;
import com.tuo51.foudation.utils.JsonUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.tuo51.foudation.constant.RequestConstant.*;

/**
 * 伙伴接口鉴权拦截器
 */

@Slf4j
@Component
public class PartnerInterceptor implements HandlerInterceptor {

    @Autowired
    MemVerificationCache cache;

    @Configuration
    @ConfigurationProperties(prefix="partners")
    @Data
    class PartnerAuthConfig{
        private Map<String, String> auths;
    }

    @Autowired
    PartnerAuthConfig authConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String partnerId = request.getHeader(PARTNERID_KEY);

        if(StringUtils.isEmpty(partnerId)){
            throw new BusinessException(ErrorCode.TICKET_REQUIRED, "你无权访问该系统！");
        }

        Map <String, String[]> params = request.getParameterMap();

        String auth = request.getHeader(AUTH_KEY);
        String reqUUID = request.getHeader(REQ_UUID_KEY);
        String compVer = request.getHeader(COMP_VERSION_KEY);
        String url = request.getRequestURL().toString();
        String perferSign = authSigh(url, params, compVer, reqUUID, partnerId);

        //签名校验
        if (!perferSign.equals(auth)){
            log.error("partner auth failed,  prefer to : " + perferSign +  "   provide is : " + auth );
            throw new BusinessException(ErrorCode.TICKET_REQUIRED, "签名错误，你无权访问该系统！");
        }

        String paramsStr = JsonUtil.toJson(params);
        log.info("system call URL:============[{}] ,params:=============[{}]", url, paramsStr);

        return true;
    }

    /**
     * 签名请求
     * @param urlStr
     * @param params
     * @param compver
     * @param reqUuid
     * @param partnerId
     * @return
     */
    public String authSigh (String urlStr, Map<String, String[]> params, String compver, String reqUuid, String partnerId){
        String path = "";
        try {
            URL url = new URL(urlStr);
            path = url.getPath();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        String signSecret = signSecretForPartner(partnerId);

        String paramStr = (params == null || params.size() == 0) ? "" : params.keySet().stream()
                .sorted()
                .map(k -> {
                   String values[] = params.get(k);
                   return k + "=" + StringUtils.join(values, ",");
                })
                .collect(Collectors.joining("&"));

        String signBase = path + paramStr + compver + reqUuid + partnerId + signSecret;
        return DigestUtils.md5Hex(signBase);
    }

    private String signSecretForPartner(String partnerId){
        String ret = authConfig.getAuths().get(partnerId);
        if (StringUtils.isEmpty(ret)){
            throw new BusinessException(ErrorCode.PROMISSION_DELINED, "权限不够");
        }
        return ret;
    }

    /**
     * 签名范例
     * @param headers
     * @param urlStr
     * @param params
     */
    public void signRequest(Map headers, String urlStr, Map params){

            String uuid = UUID.randomUUID().toString();
            headers.put(REQ_UUID_KEY, uuid);
            headers.put(COMP_VERSION_KEY, COMP_VERSION_VALUE);
            headers.put(PARTNERID_KEY, "express");
            headers.put(AUTH_KEY, authSigh(urlStr, params, COMP_VERSION_VALUE, uuid, "express"));

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
